#include <QStateMachine>
#include <QState>
#include <QTimer>
#include "eddispenser.h"
#include "sensorthread.h"

// Define enums for specific states
enum StatePages
{
	StatePageWelcome = 0,
	StatePageDrinks = 1,
	StatePageProcessing = 2,
	StatePageDispensing = 3,
	StatePageError = 4
};

EDDispenser::EDDispenser( QWidget *parent, Qt::WFlags flags ) : QMainWindow( parent, flags )
{
	ui.setupUi( this );

	this->showFullScreen();

	machine = new QStateMachine();
	// Declare and initialize states
	QState *stateWelcome = new QState();
	QState *stateDrinks = new QState();
	QState *stateProcessing = new QState();
	QState *stateDispensing = new QState();
	QState *stateError = new QState();

	// Associate states with their respective pages
	stateWelcome->assignProperty( ui.stackedWidget, "currentIndex", StatePageWelcome );
	stateDrinks->assignProperty( ui.stackedWidget, "currentIndex", StatePageDrinks );
	stateProcessing->assignProperty( ui.stackedWidget, "currentIndex", StatePageProcessing );
	stateDispensing->assignProperty( ui.stackedWidget, "currentIndex", StatePageDispensing );
	stateError->assignProperty( ui.stackedWidget, "currentIndex", StatePageError );

	stateWelcome->addTransition( ui.buttonWelcomeDrinks, SIGNAL( clicked() ), stateDrinks ); // Advance state to Drinks page
	stateDrinks->addTransition( ui.buttonDrinksSelect, SIGNAL( clicked() ), stateProcessing ); // Advance state to Processing page (Needs conditional transition)
	stateDrinks->addTransition( ui.buttonDrinksBack, SIGNAL( clicked() ), stateWelcome ); // Go to previous state
	stateProcessing->addTransition( ui.buttonProcessPurchase, SIGNAL( clicked() ), stateDispensing ); // Advance state to dispensing (Needs conditional transition)
	stateProcessing->addTransition( ui.buttonProcessBack, SIGNAL( clicked() ), stateDrinks ); // Go to previous state

	// Create timer for 5 second wait after dispensing (Simulated wait, will actually just finish once the hardware job completes)
	QTimer *timer = new QTimer( stateDispensing );
	timer->setSingleShot( true );
	timer->setInterval( 5000 );
	QObject::connect( stateDispensing, SIGNAL( entered() ), timer, SLOT( start() ) ); // Connect dispensing state to 5 second timer to restart State Machine

	stateDispensing->addTransition( timer, SIGNAL( timeout() ), stateWelcome ); // When timer times out (5 sec) roll back to welcome page
	
	machine->addState(stateWelcome);
	machine->addState(stateDrinks);
	machine->addState(stateProcessing);
	machine->addState(stateDispensing);
	machine->addState(stateError);
	machine->setInitialState(stateWelcome);
	machine->start();

	SensorThread* sensorThread = new SensorThread( this );
	sensorThread->start();
}

EDDispenser::~EDDispenser( void )
{
	delete machine;
}
